package com.mdd.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mdd.admin.service.IMansionService;
import com.mdd.admin.validate.order.MansionCreateValidate;
import com.mdd.admin.validate.order.MansionSearchValidate;
import com.mdd.admin.validate.commons.PageValidate;
import com.mdd.admin.validate.order.MansionUpdateValidate;
import com.mdd.admin.vo.order.MansionVo;
import com.mdd.common.core.PageResult;
import com.mdd.common.entity.order.Address;
import com.mdd.common.entity.order.Mansion;
import com.mdd.common.mapper.order.AddressMapper;
import com.mdd.common.mapper.order.MansionMapper;
import com.mdd.common.util.LocationUtils;
import com.mdd.common.util.TimeUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;

/**
 * 大厦服务类
 * @author shenjian
 * @createTime 2023年02月06日 22:43:00
 */
@Service
public class MansionServiceImpl implements IMansionService {

    private static final String STR_FORMAT = "0000";

    @Resource
    MansionMapper mansionMapper;

    @Resource
    AddressMapper addressMapper;

    @Override
    public PageResult<MansionVo> list(PageValidate pageValidate, MansionSearchValidate searchValidate) {
        Integer pageNo   = pageValidate.getPageNo();
        Integer pageSize = pageValidate.getPageSize();

        QueryWrapper<Mansion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);
        queryWrapper.orderByDesc("id");
        queryWrapper.select(Mansion.class, info ->
                !"is_delete".equals(info.getColumn()) &&
                !"delete_time".equals(info.getColumn()) &&
                !"update_time".equals(info.getColumn()));

        mansionMapper.setSearch(queryWrapper, searchValidate, new String[]{
                "=:sn:str",
                "like:name:str"
        });
        IPage<Mansion> iPage = this.mansionMapper.selectPage(new Page<>(pageNo, pageSize), queryWrapper);

        List<MansionVo> list = new LinkedList<>();
        for(Mansion mansion : iPage.getRecords()) {
            MansionVo vo = new MansionVo();
            BeanUtils.copyProperties(mansion, vo);
            // 计算位置
            if (searchValidate.getLatitude() != null && searchValidate.getLongitude() != null &&
                    mansion.getLatitude() != null && mansion.getLongitude() != null) {
                vo.setDistance((int) Math.round(LocationUtils.getDistance(searchValidate.getLatitude(), searchValidate.getLongitude(),
                        mansion.getLatitude(), mansion.getLongitude())));
            }
            list.add(vo);
        }

        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
    }

    @Override
    public MansionVo detail(Integer id) {
        final Mansion mansion = this.mansionMapper.selectById(id);
        MansionVo vo = new MansionVo();
        BeanUtils.copyProperties(mansion, vo);
        return vo;
    }

    @Override
    public void add(MansionCreateValidate createValidate) {
        Assert.isNull(this.mansionMapper.selectOne(new QueryWrapper<Mansion>()
                .eq("sn", createValidate.getSn())
                .last("limit 1")), "编号已存在");
        Assert.isNull(this.mansionMapper.selectOne(new QueryWrapper<Mansion>()
                .eq("name", createValidate.getName())
                .eq("is_delete", 0)
                .last("limit 1")), "大厦名称已存在");
        Mansion manual = new Mansion();
        BeanUtils.copyProperties(createValidate, manual);
        //TODO 计算坐标
        manual.setIsDelete(0);
        manual.setCreateTime(TimeUtils.timestamp());
        this.mansionMapper.insert(manual);
    }

    @Override
    public void edit(MansionUpdateValidate updateValidate) {
        Mansion mansion = this.mansionMapper.selectOne(new QueryWrapper<Mansion>()
                .eq("id", updateValidate.getId())
                .eq("is_delete", 0)
                .last("limit 1"));
        Assert.notNull(mansion, "数据错误，该大厦数据不存在！");
        Assert.isNull(this.mansionMapper.selectOne(new QueryWrapper<Mansion>()
                .eq("name", updateValidate.getName())
                .eq("is_delete", 0)
                .ne("id", updateValidate.getId())
                .last("limit 1")), "大厦名称已存在");
        BeanUtils.copyProperties(updateValidate, mansion);
        mansion.setUpdateTime(TimeUtils.timestamp());
        this.mansionMapper.updateById(mansion);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void del(Integer id) {
        Mansion mansion = this.mansionMapper.selectOne(new QueryWrapper<Mansion>()
                .eq("id", id)
                .eq("is_delete", 0)
                .last("limit 1"));
        Assert.notNull(mansion, "数据错误，该大厦数据不存在！");
        mansion.setIsDelete(1);
        mansion.setDeleteTime(TimeUtils.timestamp());
        this.mansionMapper.updateById(mansion);
        // 删除地址
        Address address = new Address();
        address.setIsDelete(1);
        address.setIsDefault(0);
        address.setDeleteTime(TimeUtils.timestamp());
        this.addressMapper.update(address, new QueryWrapper<Address>()
                .eq("is_delete", 0)
                .eq("mansion_id", id));
    }

    @Override
    public String createSn() {
        Long count = this.mansionMapper.selectCount(new QueryWrapper<>());
        count++;
        DecimalFormat df = new DecimalFormat(STR_FORMAT);
        return df.format(count);
    }
}
